package com.manong.config.handler;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.manong.config.redis.RedisService;
import com.manong.entity.User;
import com.manong.utils.JwtUtils;
import com.manong.utils.LoginResult;
import com.manong.utils.ResultCode;
import io.jsonwebtoken.Jwts;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * @author 李茂鑫
 * @Date 2025/1/13 11:51
 * @Descripition   登录成功处理器
 */
@Component
//AuthenticationSuccessHandler：处理认证成功后的逻辑
@Slf4j
public class LoginSuccessHandler implements AuthenticationSuccessHandler {
    @Resource
    private JwtUtils jwtUtils;
    @Resource
    private RedisService redisService;
    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException {
        /**
         * 参数1：HTTP请求对象，可以用于获取请求的相关信息。
         * 参数2：HTTP响应对象，用于向客户端发送响应。
         * 参数3：认证信息对象，包含了认证成功的用户的相关信息。
         */
        //设置相对应的编码格式
        response.setContentType("application/json;charset=utf-8");
        User user=(User)authentication.getPrincipal();
        //返回的是认证后的主体信息
        String token= jwtUtils.generateToken(user);
        //根据用户生成token
        long expireTime= Jwts.parser()  //解析token
                .setSigningKey(jwtUtils.getSecret())  //设置签名密钥
                .parseClaimsJws(token.replace("jwt_",""))  //解析token，replace方法用于去除jwt_前缀
                .getBody().getExpiration().getTime(); //获取过期时间
        LoginResult loginResult = new LoginResult(user.getId(), ResultCode.SUCCESS,token,expireTime);
        //创建LoginResult登录结果对象
        String result= JSON.toJSONString(loginResult, SerializerFeature.DisableCircularReferenceDetect);
        //将对象和转换成json格式返回,并消除循环引用
        //SerializerFeature.DisableCircularReferenceDetect是一个序列化特性，表示禁用循环引用检测。
        ServletOutputStream outputStream=response.getOutputStream();
        outputStream.write(result.getBytes(StandardCharsets.UTF_8));
        outputStream.flush();
        outputStream.close();
        //将token保存到redis中
        String tokenKey="token_"+token;
        redisService.set(tokenKey,token, jwtUtils.getExpiration()/1000);
    }
}
